package main

import (
	"encoding/json"
	"os"
)

const (
	linkText         = "¶"
	headlineLevel    = 2
	Blocks           = "blocks"
	PandocAPIVersion = "pandoc-api-version"
	Meta             = "meta"
	Header           = "Header"
	Link             = "Link"
	Type             = "t"
	Content          = "c"
)

func handleHeader(header map[string]interface{}) map[string]interface{} {
	c := header[Content].([]interface{})
	level := int(c[0].(float64))

	// Only link to certain headline levels
	if level != headlineLevel {
		return header
	}

	headlineArr := c[1].([]interface{})
	var blocks []map[string]interface{}

	for _, block := range c[2].([]interface{}) {
		blocks = append(blocks, block.(map[string]interface{}))
	}

	space := map[string]interface{}{Type: "Space"}
	blocks = append(blocks, space)

	headlineLink := map[string]interface{}{
		Type: Link,
		Content: []interface{}{
			[]interface{}{"", []string{}, []string{}},
			[]map[string]string{0: {"c": linkText, "t": "Str"}},
			[]string{"#" + headlineArr[0].(string), ""},
		},
	}
	blocks = append(blocks, headlineLink)

	return map[string]interface{}{
		Type: Header,
		Content: []interface{}{
			level,
			headlineArr,
			blocks,
		},
	}
}

func handleBlock(block interface{}) map[string]interface{} {
	var newBlock map[string]interface{}
	newBlock = block.(map[string]interface{})
	if newBlock[Type] == Header {
		newBlock = handleHeader(newBlock)
	}
	return newBlock
}

func mungeHeadlines(pandoc map[string]interface{}) map[string]interface{} {
	var blocks []interface{}

	for _, block := range pandoc[Blocks].([]interface{}) {
		blocks = append(blocks, handleBlock(block))
	}

	return map[string]interface{}{
		PandocAPIVersion: pandoc[PandocAPIVersion],
		Meta:             pandoc[Meta],
		Blocks:           blocks,
	}
}

func checkVersion(pandocVersion []interface{}) {
	if int(pandocVersion[0].(float64)) != 1 ||
		int(pandocVersion[1].(float64)) != 17 {
		panic("I don't work with this Pandoc API Version")
	}
}

func main() {
	decoder := json.NewDecoder(os.Stdin)

	var pandoc map[string]interface{}
	decoder.Decode(&pandoc)

	checkVersion(pandoc[PandocAPIVersion].([]interface{}))
	out := mungeHeadlines(pandoc)
	encoder := json.NewEncoder(os.Stdout)
	encoder.Encode(&out)
}
